In this project, we analyze time series forecasting using Meta’s Prophet model. Prophet is a powerful and user-friendly tool for forecasting time series data, commonly applied in predicting financial trends, stock prices, and market movements.
We will implement Prophet to forecast the EuStockMarkets dataset, which contains historical daily closing prices for major European stock indices.My objective is to develop a forecasting model, predict future stock prices, and evaluate the accuracy of these predictions.
For this analysis, we will use the R implementation of Prophet to generate insights into market trends, seasonality, and long-term financial patterns.
EuStockMarkets Dataset?The built-in EuStockMarkets dataset in R provides
daily closing prices for four major European stock
indices from 1991 to 1998:
This dataset is stored as a ts (time series)
object, meaning it has a structured time index. To use it in
Prophet, I will convert it into a data frame.
str(EuStockMarkets)## Time-Series [1:1860, 1:4] from 1991 to 1999: 1629 1614 1607 1621 1618 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:4] "DAX" "SMI" "CAC" "FTSE"
summary(EuStockMarkets)## DAX SMI CAC FTSE
## Min. :1402 Min. :1587 Min. :1611 Min. :2281
## 1st Qu.:1744 1st Qu.:2166 1st Qu.:1875 1st Qu.:2843
## Median :2141 Median :2796 Median :1992 Median :3247
## Mean :2531 Mean :3376 Mean :2228 Mean :3566
## 3rd Qu.:2722 3rd Qu.:3812 3rd Qu.:2274 3rd Qu.:3994
## Max. :6186 Max. :8412 Max. :4388 Max. :6179
1)Swiss Market (SMI) had the highest stock values overall.
-Highest median (2796), mean (3376), and max (8412) Indicates strong performance and growth over time.
2)FTSE (UK) showed strong performance but was more stable.
-Higher quartile values and mean (3566) suggest a more consistent upward trend. -Lower volatility compared to DAX and CAC.
3)DAX (Germany) had the lowest minimum (1402) but strong growth.
-Large gap between min (1402) and max (6186), suggesting higher volatility. -Fast growth and high fluctuation compared to FTSE and SMI.
4)CAC (France) had the lowest max (4388) and relatively lower values overall.
-Suggests it was the least volatile but also had lower peaks.
Analyze the historical trends of European stock indices. Use Prophet forecasting to predict future stock prices. Visualize trends, seasonality, and forecast components. Apply statistical techniques (e.g., linear regression) to understand growth patterns. Compare time frames to see how market trends evolve over time.
## Load necessary packages
library(prophet) # Forecasting model## Loading required package: Rcpp
## Loading required package: rlang
library(zoo) # Date handling##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(ggplot2)# Visualization
library(dplyr) # Data manipulation##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
eustock.df <- data.frame(
ds = as.Date(as.yearmon(time(EuStockMarkets))), # Convert to Year-Month format & Date
y = as.numeric(EuStockMarkets[, "DAX"]) # Select DAX stock index (Germany)
)
#Check the first few rows:
head(eustock.df)## ds y
## 1 1991-06-01 1628.75
## 2 1991-07-01 1613.63
## 3 1991-07-01 1606.51
## 4 1991-07-01 1621.04
## 5 1991-07-01 1618.16
## 6 1991-07-01 1610.61
#Summary of the dataset:
summary(eustock.df)## ds y
## Min. :1991-06-01 Min. :1402
## 1st Qu.:1993-04-01 1st Qu.:1744
## Median :1995-01-01 Median :2141
## Mean :1995-01-11 Mean :2531
## 3rd Qu.:1996-11-01 3rd Qu.:2722
## Max. :1998-08-01 Max. :6186
The minimum and maximum values of the DAX index show its growth over time. The mean and median values indicate the typical stock price level. The spread (range & standard deviation) suggests market volatility.
#Plot historical DAX prices:
ggplot(eustock.df, aes(x = ds, y = y)) +
geom_line(color = "blue") +
labs(title = "DAX Stock Prices (1991-1998)",
x = "Year",
y = "Stock Price") +
theme_minimal()The stock market trends upwards, reflecting economic growth. There are short-term fluctuations, indicating market volatility.
While the static ggplot2 plot in Section 2.3 shows historical trends, it lacks interactivity. To enhance analysis, we use Plotly and Dygraphs, allowing zooming, dynamic comparisons, and real-time insights. These tools provide a more flexible and detailed exploration of stock price movements.
Before applying Prophet forecasting, we first analyze historical stock trends to ensure accurate predictions. Section 3 explores price movements, volatility, and long-term growth patterns through visualizations, statistical models, and interactive tools. By examining trends, seasonality, and different time periods, we gain insights into market behavior, helping us refine our forecasting approach. This step is crucial for identifying patterns, anomalies, and key growth factors, ensuring that our predictions in Section 4 are data-driven and reliable
# Load interactive visualization libraries
library(plotly)##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(dygraphs)#Convert ggplot2 chart to an interactive Plotly chart
plotly_chart <- ggplot(eustock.df, aes(x = ds, y = y)) +
geom_line(color = "blue") +
labs(title = "DAX Stock Prices (1991-1998)",
x = "Year",
y = "Stock Price") +
theme_minimal()
#Convert to interactive Plotly
ggplotly(plotly_chart)library(xts) # Required for dygraphs##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Attaching package: 'xts'
## The following objects are masked from 'package:dplyr':
##
## first, last
eustock_ts <- xts(eustock.df$y, order.by = eustock.df$ds)
#Create an interactive Dygraph chart
dygraph(eustock_ts, main = "DAX Stock Prices (1991-1998)") %>%
dyRangeSelector() %>% # Add a range selector to zoom into specific years
dyAxis("y", label = "Stock Price") %>%
dySeries("V1", label = "DAX") %>%
dyOptions(strokeWidth = 2)# Fit a linear model
lm_model <- lm(y ~ ds, data = eustock.df)
# Display summary of the regression
summary(lm_model)##
## Call:
## lm(formula = y ~ ds, data = eustock.df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -779.95 -524.79 -38.92 383.67 2096.46
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -8.722e+03 1.581e+02 -55.16 <2e-16 ***
## ds 1.231e+00 1.724e-02 71.41 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 560.7 on 1858 degrees of freedom
## Multiple R-squared: 0.733, Adjusted R-squared: 0.7328
## F-statistic: 5100 on 1 and 1858 DF, p-value: < 2.2e-16
The linear regression model shows a strong positive trend in DAX stock prices over time. The coefficient for ds (1.231) indicates that the stock price increases by approximately 1.23 units per day, reinforcing a consistent upward trajectory.
The R-squared value (0.733) suggests that 73.3% of the stock price variation is explained by time, demonstrating a strong relationship between time and price growth. The highly significant p-value (<2.2e-16) confirms that this trend is statistically significant.
Given its steady growth, strong trend, and statistical reliability, DAX appears to be a good stock option for long-term investment, particularly for those seeking consistent market appreciation.
# Subset data for early (1991-1994) and late (1995-1998) periods
early_data <- eustock.df[eustock.df$ds < as.Date("1995-01-01"), ]
late_data <- eustock.df[eustock.df$ds >= as.Date("1995-01-01"), ]
# Plot early period
ggplot(early_data, aes(x = ds, y = y)) +
geom_line(color = "red") +
labs(title = "DAX (1991-1994)", x = "Year", y = "Stock Price") +
theme_minimal()# Plot late period
ggplot(late_data, aes(x = ds, y = y)) +
geom_line(color = "green") +
labs(title = "DAX (1995-1998)", x = "Year", y = "Stock Price") +
theme_minimal()The market was relatively stable early on. Steeper growth is visible in the late 1990s, possibly due to stronger economic conditions.
# Create Prophet model
m <- prophet(eustock.df)## Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.
## Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.
# Generate future dates (365 days ahead)
future <- make_future_dataframe(m, periods = 365, freq = "day")
# Predict future values
forecast <- predict(m, future)# Create an interactive Plotly forecast chart
forecast_plotly <- plot_ly() %>%
add_trace(x = forecast$ds, y = forecast$yhat, type = "scatter", mode = "lines", name = "Forecast", line = list(color = "blue")) %>%
add_trace(x = forecast$ds, y = forecast$yhat_lower, type = "scatter", mode = "lines", name = "Lower Bound", line = list(dash = "dot", color = "gray")) %>%
add_trace(x = forecast$ds, y = forecast$yhat_upper, type = "scatter", mode = "lines", name = "Upper Bound", line = list(dash = "dot", color = "gray")) %>%
layout(title = "DAX Stock Price Forecast (Prophet Model)",
xaxis = list(title = "Year"),
yaxis = list(title = "Stock Price"))
forecast_plotly # Display the interactive forecastforecast <- predict(m, future)
# Plot forecast
plot(m, forecast)forecast <- predict(m, future)This project successfully analyzed historical trends of European stock indices, with a focus on DAX (Germany). Through exploratory data analysis, interactive visualizations, and statistical modeling, we identified long-term growth patterns and market fluctuations.
Using Prophet forecasting, we predicted future DAX stock prices, showing a continued upward trend with varying confidence intervals. The interactive Plotly visualization highlighted seasonality and uncertainty, while linear regression confirmed a strong positive trend over time.
By comparing different time frames, we observed market evolution, reinforcing the importance of data-driven forecasting. The combination of historical analysis, statistical modeling, and forecasting tools makes this approach a valuable framework for predicting future stock market trends.
Based on our findings, DAX shows strong long-term growth potential, making it a good investment option for long-term investors. However, short-term fluctuations and market volatility suggest that investors should consider risk tolerance and broader economic conditions before making a decision.